﻿Public Class SettingsMenuBuilder
  Private _rootMenu As New MobilePrettyGui.EnumerableInterfaceList(Of SettingsEntry, MobilePrettyGui.iPrettyListItem)
  Private _settingsMenus As New List(Of SettingsSection)
  Private _curSettingsMenu As SettingsSection = Nothing
  Private _location As SettingsLocation = SettingsLocation.Sections

  Public Enum SettingsLocation
    Sections = 0
    Entries = 1
  End Enum

  Public Class SettingsSection
    Private _sectionKey As String = String.Empty
    Private _sectionName As String = String.Empty
    Private _settingsList As New MobilePrettyGui.EnumerableInterfaceList(Of SettingsEntry, MobilePrettyGui.iPrettyListItem)

    Public Property SectionKey() As String
      Get
        Return Me._sectionKey
      End Get
      Set(ByVal value As String)
        Me._sectionKey = value
      End Set
    End Property

    Public Property SectionName() As String
      Get
        Return Me._sectionName
      End Get
      Set(ByVal value As String)
        Me._sectionName = value
      End Set
    End Property

    Public ReadOnly Property Entries() As MobilePrettyGui.EnumerableInterfaceList(Of SettingsEntry, MobilePrettyGui.iPrettyListItem)
      Get
        Return Me._settingsList
      End Get
    End Property
  End Class

  Public Sub New()
    Me.ReloadSettingSchema()
  End Sub

  Public ReadOnly Property Items() As MobilePrettyGui.EnumerableInterfaceList(Of SettingsEntry, MobilePrettyGui.iPrettyListItem)
    Get
      Select Case Me._location
        Case SettingsLocation.Sections
          Return Me._rootMenu
        Case SettingsLocation.Entries
          If Me._curSettingsMenu IsNot Nothing Then
            Return Me._curSettingsMenu.Entries
          End If
      End Select

      Return Nothing
    End Get
  End Property

  Public Property Location() As SettingsLocation
    Get
      Return Me._location
    End Get
    Set(ByVal value As SettingsLocation)
      Me._location = value
    End Set
  End Property

  Public ReadOnly Property CanGoPreviousMenu() As Boolean
    Get
      Return Me._location = SettingsLocation.Entries
    End Get
  End Property

  Public Sub LoadMenu(ByVal key As String)
    Me._location = SettingsLocation.Sections
    Me._curSettingsMenu = Nothing
    For Each s As SettingsSection In Me._settingsMenus
      If String.Compare(s.SectionKey, key, True) = 0 Then
        Me._location = SettingsLocation.Entries
        Me._curSettingsMenu = s
        Exit Sub
      End If
    Next
  End Sub

  Public Sub ClearSettingsSections()
    For Each s As SettingsSection In Me._settingsMenus
      s.Entries.Clear()
    Next

    If Me._curSettingsMenu IsNot Nothing Then
      Me._curSettingsMenu.Entries.Clear()
      Me._curSettingsMenu = Nothing
    End If

    Me._rootMenu.Clear()
    Me._settingsMenus.Clear()
  End Sub

  Public Sub ReloadSettingSchema()
    Me.ClearSettingsSections()

    ' WITH the schema section as we directly look at it here instead of the settings class
    With Settings.GetSettingsSchema
      ' Find all the sections; they are delimited by a space
      Dim secsSrcStr As String = .StringValue("Sections")
      If secsSrcStr IsNot Nothing AndAlso secsSrcStr.Length > 0 Then
        Dim secs() As String = secsSrcStr.Split(" ")
        If secs IsNot Nothing Then
          For Each s As String In secs
            Dim ss As New SettingsSection
            Dim se As New SettingsEntry

            ' Set the section key
            ss.SectionKey = s.Trim.ToUpper
            se.Key = ss.SectionKey

            ' Set the section name based on the language file
            ss.SectionName = Language.GetLanguageString(ss.SectionKey)
            se.Text = ss.SectionName

            ' Add entries to collection
            Me._rootMenu.Add(se)
            Me._settingsMenus.Add(ss)
          Next
        End If
      End If

      ' Now look at every entry in the schema section and populate the appropriate SettingsSection instances
      For Each k As String In .Keys
        Dim schemaKey() As String = k.Split("_") ' the 'Sections' key will fail here, so no need to check for it specifically
        If schemaKey.Count = 2 Then ' MUST equal 2 (0 = section, 1 = setting)
          ' Look through all our sections to find the section that applies to this key
          For Each ss As SettingsSection In Me._settingsMenus
            If ss.SectionKey = schemaKey(0).Trim.ToUpper Then
              ' Look at the value to parse
              Dim values() As String = .StringValueNoNull(k).Split(" ")
              If values.Count >= 2 Then
                ' Now add the properties of this setting
                Dim se As New SettingsEntry

                ' Set the keys to associate the setting in the INI file that this targets
                se.Schema.SectionKey = ss.SectionKey
                se.Schema.SettingsKey = schemaKey(1).Trim.ToUpper

                ' Set the text values for display
                se.Text = Language.GetLanguageString(se.Schema.SettingsKey)
                se.Subtext = Language.GetLanguageStringNoMissing(se.Schema.SettingsKey & "_Desc")

                ' Set the value for if a restart is required
                If values(0).Trim = "0" Then
                  se.Schema.RestartRequired = False
                ElseIf values(0).Trim = "1" Then
                  se.Schema.RestartRequired = True
                Else ' invalid setting, so exit without adding this setting entry
                  ErrorLog.WriteToErrorLog("SettingsMenuBuilder.ReloadSettingSchema :: invalid restart value :: " & values(0).Trim)
                  Exit For
                End If

                ' Look at the type...
                Select Case values(1).Trim.ToUpper
                  Case "BOOL"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.BOOL
                    With Settings.ValueInteger(se.Schema.SectionKey, se.Schema.SettingsKey)
                      If .HasValue Then
                        se.IntValue = .Value
                      End If
                    End With

                  Case "CONTROL_EDITOR"
                    ' This is a special type that brings up the control editor for editing the controls.ini, no other data needs to be saved because it is not used
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.CONTROL_EDITOR

                  Case "STREAMREGEX_EDITOR"
                    ' This is a special type that brings up the regex editor for editing the regex.ini, no other data needs to be saved because it is not used
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.STREAMREGEX_EDITOR

                  Case "SUBSCRIPTION_EDITOR"
                    ' This is a special type that brings up the regex editor for editing the regex.ini, no other data needs to be saved because it is not used
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.SUBSCRIPTION_EDITOR

                  Case "INT"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.INT
                    With Settings.ValueInteger(se.Schema.SectionKey, se.Schema.SettingsKey)
                      If .HasValue Then
                        se.IntValue = .Value
                      End If
                    End With

                    ' Look for int minimum value
                    If values.Count >= 3 Then
                      If values(2).Trim.ToUpper <> "X" Then
                        ' Any error here, we just assume no limit, same as "X" except an exception will be thrown, obviously
                        Try : se.Schema.IntMinimum = Integer.Parse(values(2)) : Catch : End Try
                      End If
                    End If

                    ' Look for int maximum value
                    If values.Count >= 4 Then
                      If values(3).Trim.ToUpper <> "X" Then
                        ' Any error here, we just assume no limit, same as "X" except an exception will be thrown, obviously
                        Try : se.Schema.IntMaximum = Integer.Parse(values(3)) : Catch : End Try
                      End If
                    End If

                    ' Look for step value
                    If values.Count >= 5 Then
                      If values(4).Trim.ToUpper <> "X" Then
                        ' Any error here, we just assume a step of '1' (default)
                        Try : se.Schema.IntStep = Integer.Parse(values(4)) : Catch : End Try
                      End If
                    End If

                  Case "LANGUAGE"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.LANGUAGE
                    Dim str As String = Settings.ValueString(se.Schema.SectionKey, se.Schema.SettingsKey)
                    If str IsNot Nothing Then
                      se.StringValue = str
                    End If

                  Case "FILE"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.FILE
                    Dim str As String = Settings.ValueString(se.Schema.SectionKey, se.Schema.SettingsKey)
                    If str IsNot Nothing Then
                      se.StringValue = str
                    End If

                  Case "FOLDERS"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.FOLDERS
                    se.StringValue = Settings.ValueListString(se.Schema.SectionKey, se.Schema.SettingsKey, ":")

                  Case "RADIO"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.RADIO

                    ' Look for radio items
                    For i As Integer = 2 To values.Count - 1
                      Dim rs() As String = values(i).Split("|")
                      If rs.Count = 2 Then
                        Dim re As New SettingsEntry.SchemaSettings.RadioEntry
                        re.Value = rs(0)
                        re.LanguageString = Language.GetLanguageString(rs(1))
                        se.Schema.RadioButtons.Add(re)
                      End If
                    Next
                    If se.Schema.RadioButtons.Count <= 0 Then
                      ' No valid options, so we need to exit as this is invalid
                      ErrorLog.WriteToErrorLog("SettingsMenuBuilder.ReloadSettingSchema :: No valid radio items.")
                      Exit For
                    Else
                      se.StringValue = Settings.ValueString(se.Schema.SectionKey, se.Schema.SettingsKey)
                    End If

                  Case "STRING_LIST"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.STRING_LIST
                    se.StringValue = Settings.ValueListString(se.Schema.SectionKey, se.Schema.SettingsKey, vbCr)

                  Case "REGEX_PATH"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.REGEX_PATH
                    Dim str As String = Settings.ValueString(se.Schema.SectionKey, se.Schema.SettingsKey)
                    If str IsNot Nothing Then
                      se.StringValue = str
                    End If

                  Case "SKIN"
                    se.Schema.SchemaType = SettingsEntry.SchemaSettings.SchemaTypeEnum.SKIN
                    Dim str As String = Settings.ValueString(se.Schema.SectionKey, se.Schema.SettingsKey)
                    If str IsNot Nothing Then
                      se.StringValue = str
                    End If

                  Case Else ' invalid type, so exit without adding this entry
                    ErrorLog.WriteToErrorLog("SettingsMenuBuilder.ReloadSettingSchema :: Invalid schema type :: " & values(1).Trim)
                    Exit For
                End Select

                ' All parameters are valid, so add the section entry to the schema section
                ss.Entries.Add(se)
                Exit For
              End If
            End If
          Next
        End If
      Next
    End With
  End Sub
End Class
